package cn.itsource.course.service.impl;

import cn.itsource.course.domain.CourseType;
import cn.itsource.course.mapper.CourseTypeMapper;
import cn.itsource.course.service.ICourseTypeService;
import cn.itsource.course.vo.CrumbsVO;
import cn.itsource.feignclient.FeignClientt;
import cn.itsource.hrm.constant.RedisKeyConstant;
import cn.itsource.util.AjaxResult;
import cn.itsource.feignclient.PageFeignClientt;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;

import static cn.itsource.hrm.pagestatic.PageStatic.COURSE_TYPE_STATIC;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author zd
 * @since 2020-02-19
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
    @Autowired
    private FeignClientt feignClientt;
    @Autowired
   private PageFeignClientt pageFeignClientt;
    //抽取公共的方法  每次对数据库都进行查询
    public   List<CourseType> resetSelectAll(){
        List<CourseType> listRsult =  baseMapper.selectList(null);
//            将数据库查询的结果保存在redis数据库中
//            JSON.toJSONString(list):将数组转化为json格式的字符串
        //:courseTypes,后面再调用页面静态化服务的时候，需要需要封装数据，因为谁调用才知道model中的存入的是什么key
        Map<String,Object> model=new HashMap<>();
        model.put("courseTypes",listRsult);
        AjaxResult ajaxResult = feignClientt.set(RedisKeyConstant.COURSE_TYPE, JSON.toJSONString(model));
        if (!ajaxResult.isSuccess()) {
            throw new RuntimeException("redis保存数据失败");
        }
        return listRsult;
    }
    @Override
    public List<CourseType> treeData() {
        List<CourseType> list =null;
        //通过redis查询数据
        // 常量RedisKeyConstant.COURSE_TYPE对redis的key进行常量的抽取，成为全局的常量，其他模块需要使用的话，需要引入该模块
        AjaxResult ajaxResult = feignClientt.get(RedisKeyConstant.COURSE_TYPE);
        //判断是否有数据
        if(ajaxResult.isSuccess()&& null!=ajaxResult.getResultObj()){
            //得到字符串格式结果
            String  resultResultObj = ajaxResult.getResultObj().toString();
            //将字符串格式的转换为list
            list=   JSON.parseArray(resultResultObj,CourseType.class);
        }else {
            list=  resetSelectAll();
        }

//       查询所有的课程类型

        //存放含有pid的元素
        List<CourseType> listPid=new ArrayList<CourseType>();
        for (CourseType courseType : list) {
//转化为基本数据类型 getPid().longValue()
            if (courseType != null && courseType.getPid().longValue() == 0) {
                //这里面存的全部都是pid为零的，顶级
                listPid.add(courseType);
            } else {
                //下面是pid不为零的数据,那么就不是一级分类，是子分类
//                CourseType subcategory=null;
//                创建一个数组，
                for (CourseType sonCourse : list) {
                    if (courseType.getPid().longValue() == sonCourse.getId().longValue()) {
//                        如果子分类的pid和某一个分类的id相同，那么这个分类为这个子分类的父分类
                        //得到children，然后将这个子分类，放入父分类的children中去
                        List<CourseType> children = sonCourse.getChildren();
                        children.add(courseType);
                        break;
                    }
                }
            }
        }
        return listPid;
    }
//面包屑
    @Override
    public List<CrumbsVO> crumbs(Long id ) {
        List<CrumbsVO> crumbsVOS=new ArrayList<>();
        //根据传过来来的参数查询
        CourseType courseType = baseMapper.selectById(id);
        //得到这个节点所包含的所有节点，更具数据库查询
        String courseTypePath = courseType.getPath();
        //整理数据
        String typePath=courseTypePath.startsWith(".")?courseTypePath.substring(1):courseTypePath;
        String path=typePath.endsWith(".")?typePath.substring(0,typePath.length()-1):typePath;
        //对整理的字符串进行拆分
        String[] split = path.split("\\.");
        //遍历所有的节点
        for (String type : split) {
            CrumbsVO vo=new CrumbsVO();
            //根据id查询一个节点
            long pid = Long.parseLong(type);
            CourseType courseType1 = baseMapper.selectById(type);
            //将查询的结果放在OwnerProductType（父节点）
            vo.setOwnerProductType(courseType1);
            //查询同级别的节点
            List<CourseType> list=  baseMapper.selectByPid(pid);
            //从其他节点中将自己去除
            //           list.forEach(e->{
//                if (e.getId().longValue()==courseType.getId().longValue()){
//                    list.remove(e) ;
//                }
//            });
            //4.删除自己（使用迭代器，如果使用lamda表达式会报null）
            Iterator<CourseType> iterator = list.iterator();
            while (iterator.hasNext()){
                if(iterator.next().getId().equals(courseType.getId())){
                    iterator.remove();
                    break;
                }
            }

            //将同级别的节点放在一起
            vo.setOtherProductTypes(list);
            crumbsVOS.add(vo);
        }
        return crumbsVOS;
    }

    @Override
    public boolean insert(CourseType entity) {
        //对数据进行添加的时候，对redis也进行更新处理  成功
        boolean insertSuccess = super.insert(entity);
        resetSelectAll();
        pageStatic();
        return insertSuccess;
    }

    @Override
    public boolean deleteById(Serializable id) {
        boolean deleteSuccess = super.deleteById(id);
        resetSelectAll();
        pageStatic();
        return deleteSuccess;
    }

    @Override
    public boolean updateById(CourseType entity) {
        boolean updateSuccess = super.updateById(entity);
        resetSelectAll();
        pageStatic();
        return updateSuccess;
    }
    //做课程分类的页面静态化，当课程分类的数据发生变化的时候，页面静态化的数据也将跟着修改
    public  void pageStatic(){
        //准备数据
        List<CourseType> courseTypes = this.treeData();
        //将数据存入redis中
        AjaxResult result = feignClientt.set("course_type_stattic", JSON.toJSONString(courseTypes));
        //判断是否将数据存入Redis中
        if(!result.isSuccess()){
            throw  new RuntimeException("数据存入redis失败"+result.getMessage());
        }
        String pageName="home";
        //进行页面静态化，使用feign去调用页面静态化服务
        AjaxResult pageStatic = pageFeignClientt.pageStatic(COURSE_TYPE_STATIC, pageName);
        if (!pageStatic.isSuccess()) {
            throw  new RuntimeException("数据静态化失败"+pageStatic.getMessage());
        }
    }
}
